/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jigdo.DiskIO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import jigdo.JigdoException;
import jigdo.downloader.DownloadStatus;

/**
 * Class to track the status of the image and its accompanying downloads.
 *
 * @author John R Sohn
 */
public class ProgressFile {

    /**
     * Sets parent logging mechanism
     * @param parent 
     */
    public void setParentLogger(Logger parent) {
        logger.setParent(parent);
    }
    
    public boolean isComplete()
    {
        boolean res = this.InitialImageWritten;
        
        for (int x =0; x < Entries.size();x++)
        {
            res = res && Entries.get(x).Written;
            
            if (!res)
            {
                return res;
            }
        }
        
        return res;
    }
   
    
    /**
     * Classes local logger instance
     */
    Logger logger = Logger.getLogger(this.getClass().getName());
    
    public boolean InitialImageWritten;
    
    public ArrayList<ProgressEntry> Entries;
    
    /**
     * Progress file's name.
     */
    private String FileName;

    /**
     * Reads the progress file and all entries from the provided file path or creates a new one.
     * @param src Source input stream.
     * @throws IOException File error
     * @throws ClassNotFoundException Parsing error
     */
    public void ReadThis(InputStream src) throws IOException, ClassNotFoundException {
        java.io.ObjectInputStream oi = new ObjectInputStream(src);

        this.InitialImageWritten = oi.readBoolean();
        int num = oi.readInt();

        for (int i = 0; i < num; i++) {
            Entries.add((ProgressEntry) oi.readObject());
        }

    }

    /**
     * Writes this object to the progress file.
     * @throws FileNotFoundException 
     * @throws IOException 
     */
    public void WriteThis() throws FileNotFoundException, IOException {
        FileOutputStream fo = new FileOutputStream(FileName);
        ObjectOutputStream oo = new ObjectOutputStream(fo);

        oo.writeBoolean(InitialImageWritten);
        oo.writeInt(Entries.size());

        for (int i = 0; i < Entries.size(); i++) {
            oo.writeObject(Entries.get(i));
        }

        oo.flush();
        fo.flush();
        fo.close();

    }
    
    private ISOWriter Parent;
    
   
    /**
     * Constructor. Attempts to load or create a progress entry file.
     * @param fileName The file path of the progress file.
     * @param deleteOnError Indicates whether file should be deleted and recreated if an error occurs
     * @throws JigdoException 
     */
    public ProgressFile(String fileName, boolean deleteOnError, ISOWriter parent) throws JigdoException {
        FileName = fileName;

        this.Entries = new ArrayList<ProgressEntry>();
        this.Parent = parent;
        
        if (java.nio.file.Files.exists(Paths.get(fileName), LinkOption.NOFOLLOW_LINKS)) {
            try {
                FileInputStream fi = new FileInputStream(fileName);

                ReadThis(fi);

                fi.close();
            } catch (Exception e) {
                logger.log(Level.FINER, "ProgressFile in bad format.");

                if (deleteOnError) {
                    try {
                        Files.delete(Paths.get(fileName));

                        this.Entries = new ArrayList<ProgressEntry>();
                        this.InitialImageWritten = false;

                    } catch (Exception e2) {
                        throw new JigdoException("Could not delete the malformed file.", e2);

                    }
                } else {
                    throw new JigdoException("Error occurred while parsing progress file", e);
                }
            }


        } else {
            try {
                this.WriteThis();
            } catch (Exception e) {
                throw new JigdoException("Error while writing the new progress file.", e);
            }
        }
        
   
    }
    
    public void ResetAll()
    {
        for (int x=0; x < Entries.size(); x++)
        {
            Entries.get(x).Written=false;
            
            Entries.get(x).Parent.setDownloadStatus(DownloadStatus.NotStarted);
        }
    }
}
